﻿#define ONGUI_DEBUG
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;

public class TcpServerModule : NetModuleBase
{

    public List<ClientBase> userList = new List<ClientBase>(); 
    public int clientNum = 0;

#if ONGUI_DEBUG
    /// <summary>
    /// 是否处于Debug模式
    /// </summary>
    [SerializeField]
    protected bool isDebug = true;
#endif

    /// <summary>
    /// 服务器是否正在运行
    /// </summary>
    [SerializeField]
    private bool serverIsRun = false;

   
    /// <summary>
    /// 服务器
    /// </summary>
    private TcpServerCore serverCore;

    /// <summary>
    /// 收到的消息长度
    /// </summary>
    private long receiveCount = 0;
    private long lastReceiveCount = 0;
    private long transmissionRate = 0;

#region 单例设置
    private static TcpServerModule _instance;
    public static TcpServerModule Instance
    {
        get
        {
            if (_instance == null) throw new System.Exception("单例为空，禁止调用");
            return _instance;
        }
    }

    private void Awake()
    {
        if (_instance == null)
        {
            _instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else if (Instance != this)
        {
            Destroy(gameObject);
            return;
        }
        serverCore = new TcpServerCore();
        NetCore.InitNetCore(AddEvent);
    }
#endregion

    // Use this for initialization
    void Start()
    {

        InvokeRepeating("CalcReceiveSpeed", 0, 1);
    }


    void CalcReceiveSpeed()
    {
        transmissionRate = receiveCount - lastReceiveCount;
        transmissionRate = transmissionRate > 0 ? transmissionRate : 0;
        lastReceiveCount = receiveCount;
    }

#if ONGUI_DEBUG
    #region OnGUI 测试部分
    [Space]
    [SerializeField]
    private int fontSize = 20;

    private bool isInitOnGUI = false;
    private void OnGUI()
    {
        if (!isDebug) return;
        //开始一个显示区域
        GUILayout.BeginArea(new Rect(0, 0, Screen.width, Screen.height));

        //开始最外层横向布局
        GUILayout.BeginHorizontal();
        //嵌套一个纵向布局
        GUILayout.BeginVertical();
        {
            //左上
            TestGUI();
        }
        //两个box之间上下对齐
        GUILayout.FlexibleSpace();
        {
            //左下
        }
        //结束嵌套的纵向局部
        GUILayout.EndVertical();

        //布局之间左右对齐
        GUILayout.FlexibleSpace();

        //嵌套一个纵向布局
        GUILayout.BeginVertical();

        {
            //右上
        }
        //两个box之间上下对齐
        GUILayout.FlexibleSpace();
        {
            //右下
        }
        //结束嵌套的纵向局部
        GUILayout.EndVertical();

        //结束最外层横向布局
        GUILayout.EndHorizontal();
        //结束显示区域
        GUILayout.EndArea();
    }
    private void TestGUI()
    {
        if (!isInitOnGUI)
        {
            isInitOnGUI = true;
            GUI.skin.button.fontSize = fontSize;
            GUI.skin.textArea.fontSize = fontSize;
            GUI.skin.textField.fontSize = fontSize;
            GUI.skin.label.fontSize = fontSize;
            GUI.skin.toggle.fontSize = fontSize;
        }

        if (!serverIsRun)
        {
            GUILayout.BeginHorizontal();
            GUILayout.Label("IP:");
            ip = GUILayout.TextField(ip, 15);
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("Port:");
            port = GUILayout.TextField(port, 5);
            GUILayout.EndHorizontal();
            isPacketDecode = GUILayout.Toggle(isPacketDecode, "按照长度解析");
            if (GUILayout.Button("创建服务器"))
            {
                StartServer();
            }
        }
        else
        {
            serverCore.GetParas(ref clientNum);
            GUILayout.Label("ReceiveBytes:" + receiveCount);
            GUILayout.Label("transmissionRate:" + (transmissionRate) + "b/s");
            GUILayout.Label("connect num:" + clientNum);
            if (GUILayout.Button("关闭服务器"))
            {
                CloseServer();
            }
        }
    }
    #endregion
#endif

    /// <summary>
    /// 启动服务器
    /// </summary>
    public void StartServer()
    {
        if (!serverIsRun)
        {
            serverIsRun = serverCore.StartServer(ip, port, isPacketDecode, AddEvent);
        }

    }
    /// <summary>
    /// 关闭服务器
    /// </summary>
    public void CloseServer()
    {

        serverCore.CloseServer();
        serverIsRun = false;
        HandleEventList();
        receiveCount = 0;
    }

    private void OnDestroy()
    {
        CloseServer();
        NetCore.ResetNetCore(AddEvent);
    }

    /// <summary>
    /// 广播消息
    /// 发送消息到队列 外部发送消息统一调用接口
    /// </summary>
    /// <param name="msg"></param>
    public void SendMsgToQueue(byte[] msg)
    {

        if (isPacketDecode)
        {
            if (msg.Length <= 4 && !serverIsRun) return;
            byte[] buff = System.BitConverter.GetBytes(msg.Length);
            buff = buff.Concat(msg).ToArray();
            lock (sendList)
                sendList.Add(buff);
        }
        else
        {
            if (msg.Length <= 0 && !serverIsRun) return;
            lock (sendList)
                sendList.Add(msg);
        }
    }

    /// <summary>
    /// 发送消息
    /// </summary>
    protected override void SendAllMsg()
    {
        if (sendList.Count <= 0) return;

        byte[][] msgs = null;
        lock (sendList)
        {
            msgs = sendList.ToArray();
            sendList.Clear();
        }
        for (int i = 0; i < msgs.Length; i++)
        {
            serverCore.BroadCastMessage(msgs[i]);
        }
    }

    protected override void Comm_IPEndPointError(string msg)
    {
        NetCore.LogWarning(msg);
    }
    protected override void Comm_SARThreadFailed(string msg)
    {
        NetCore.LogWarning(msg);
    }

    protected override void SS_ReceiveMessage(byte[] msg, ClientBase sender)
    {
        int count = userList.Count;
        NetCore.Log(Encoding.UTF8.GetString(msg));
        byte[] sendBuf = msg;
        if(isPacketDecode)
        {
            sendBuf = System.BitConverter.GetBytes(msg.Length).Concat(sendBuf).ToArray();
        }

        //广播消息
        for (int i = 0; i < count; i++)
            userList[i].Send(sendBuf);
        
        if (isPacketDecode)
        {
            receiveCount += 4;
        }
        receiveCount += msg.Length;
    }

    /// <summary>
    /// 断开时调用
    /// </summary>
    /// <param name="msg">断开详情</param>
    protected override void SS_Disconnect(string msg, ClientBase sender)
    {
        NetCore.Log(msg);
        receiveCount = 0;
        userList.Remove(sender);
    }
   
    protected override void SS_ServerStartFailed(string msg)
    {
        NetCore.LogWarning(msg);
    }
    protected override void SS_ServerStartSuccess(string msg)
    {
        NetCore.Log(msg);
    }
    protected override void SS_CloseServer(string msg)
    {
        NetCore.Log(msg);
    }
    protected override void SS_ClientConnectFailed(string msg)
    {
        NetCore.LogWarning(msg);
    }
    protected override void SS_ClientConnectSuccess(ClientBase sender)
    {
        NetCore.Log("客户端连接");
        userList.Add(sender);
    }

}
